package com.agentfactory.teleoreactive.interpreter.mentalstate;

import java.util.LinkedList;
import java.util.List;

import com.agentfactory.logic.update.lang.IFormula;
import com.agentfactory.logic.update.lang.ITerm;
import com.agentfactory.logic.update.lang.Predicate;
import com.agentfactory.logic.update.lang.Variable;
import com.agentfactory.logic.update.reasoner.Bindings;
import com.agentfactory.logic.update.reasoner.IQueryEngine;
import com.agentfactory.logic.update.reasoner.QueryResult;
import com.agentfactory.teleoreactive.interpreter.Utilities;

public class TRProgram {
	private List<TRRule> rules;
	private String name;
	private List<ITerm> arguments;
	private Predicate function;

	public TRProgram(String name, List<TRRule> rules, List<ITerm> args) {
		this.name = name;
		this.rules = rules;
		this.arguments = args;

	}

	public TRProgram(Predicate f, List<TRRule> rules) {
		this.rules = rules;
		this.function = f;
	}

	/**
	 * @return the list of teleo-reactive rules
	 */
	public List<TRRule> getRules() {
		return rules;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @return the arguments
	 */
	public List<ITerm> getArguments() {
		return arguments;
	}

	/**
	 * 
	 * @param queryEngine
	 * @return
	 */
	public IFormula execute(IQueryEngine queryEngine, LinkedList<ITerm> linkedList) {
		Bindings solution = new Bindings();
		for (int i = 0; i < arguments.size(); i++) {
			solution.addBinding((Variable) arguments.get(i), linkedList.get(i));
		}
		LinkedList<TRRule> boundRules = new LinkedList<TRRule>();
		for (TRRule r : rules) {
			TRRule br = r.apply(solution);
			boundRules.add(br);
		}
		for (TRRule rule : boundRules) {
			QueryResult result = queryEngine.query(rule.getCondition());
//			System.out.println("Result for Query: "+Utilities.presenter.toString(rule.getCondition())+" is "+(result.found));
			if (result.found) {
				if (!result.bindings.isEmpty())
					return rule.apply(result.bindings.get(0)).getAction();
				else
					return rule.getAction();
			}
		}
		return boundRules.getFirst().getAction();
	}

}
